/**
 *
 */
package de.cbf.cam.dsa.item;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.cbf.cam.dsa.item.act.ActivatorItem;
import de.cbf.cam.dsa.item.interfaces.ICompositeEditItem;
import de.cbf.cam.dsa.item.interfaces.ICompositeEditShapeness;
import de.cbf.cam.dsa.item.model.entities.Item;
import de.cbf.cam.dsa.item.ui.view.ViewBrokenness;
import de.cbf.cam.dsa.item.ui.view.ViewDirtiness;


/**
 * @author Alti
 *
 */
public class ControllerEditItem extends AbstractControllerEdit  {
	private static final Log logger = LogFactory.getLog(ControllerEditItem.class);

    protected ICompositeEditItem view;

    protected Item original;
    protected Item changed;
    /**
     *
     */
    public ControllerEditItem() {

    }

    @Override
	protected void regardNotification(Integer index) {
		// notification about closed shapeness controller(?)

	}

    @Override
	protected void executeCommand(int index, Object... parameters) {
    	switch (index) {
		case ICompositeEditItem.INDEX_COMMAND_EDIT_BROKENNESS_LEVELS:
			executeEditBrokennessLevels(parameters);
			break;
		case ICompositeEditItem.INDEX_COMMAND_EDIT_DIRTINESS_LEVELS:
			executeEditDirtinessLevels(parameters);
			break;

		default:
			break;
		}

	}

    protected void executeEditBrokennessLevels(Object[] parameters) {
		// get view for edit of fBrokenness
    	ControllerEditShapeness controllerBrokenness = new ControllerEditShapeness();
    	ViewBrokenness viewBrokenness =(ViewBrokenness) ActivatorItem.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(ViewBrokenness.ID);
    	ICompositeEditShapeness composite = viewBrokenness.getComposite();
    	controllerBrokenness.setView(composite);
    	controllerBrokenness.setShapeness(changed.getBrokenness());
	}

    protected void executeEditDirtinessLevels(Object[] parameters) {
		// get view for edit of dirtiness
    	ControllerEditShapeness controllerBrokenness = new ControllerEditShapeness();
    	ViewDirtiness viewBrokenness =(ViewDirtiness) ActivatorItem.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(ViewDirtiness.ID);
    	ICompositeEditShapeness composite = viewBrokenness.getComposite();
    	controllerBrokenness.setView(composite);
    	controllerBrokenness.setShapeness(changed.getBrokenness());
	}


	/**
     * set values of changed entity in view
     */
    protected void updateViewData(){
    	//port checks, updating is nonsense if model or view is missing
    	if(view == null){
			return;
		}
		if(changed == null){
			return;
		}
		updateBrokennessLevels	(changed.getBrokenessDescriptions());
		updateDescription		(changed.getDescription());
		updateDirtinessLevels	(changed.getDirtinessDescriptions());
		updateName				(changed.getName());
		updateQualityCurrent	(changed.getQuality());
		updateQualityMax		(changed.getQualityMax());
		updateQualityMin		(changed.getQualityMin());
		updateType				(changed.getType());
		updateWeight			(changed.getWeight());
        //TODO if item is garment/container etc. set according modes and data in view
    }


    protected void updatePropertyInView(int index,Object newValue){
		if(view == null){
			return;
		}
		switch (index) {
			case Item.PI_BROKENNESS:
				updateBrokenness(newValue);
				break;
			case Item.PI_BROKENNESS_LEVELS:
				updateBrokennessLevels(newValue);
				break;
			case Item.PI_DESCRIPTION:
				updateDescription(newValue);
				break;
			case Item.PI_DIRTINESS:
				updateDirtiness(newValue);
				break;
			case Item.PI_DIRTINESS_LEVELS:
				updateDirtinessLevels(newValue);
				break;
			case Item.PI_QUALITY_CURRENT:
				updateQualityCurrent(newValue);
				break;
			case Item.PI_QUALITY_MAX:
				updateQualityMax(newValue);
				break;
			case Item.PI_QUALITY_MIN:
				updateQualityMin(newValue);
				break;
			case Item.PI_TYPE:
				updateType(newValue);
				break;
			case Item.PI_WEIGHT:
				updateWeight(newValue);
				break;
			case Item.PI_NAME:
				updateName(newValue);
				break;

		    default:
				logger.warn("unknown property changed: "+index+", value: "+newValue );
				break;
		}
    }

    protected void updateBrokenness(Object newValue) {
		//current fBrokenness not shown in view
	}

    protected void updateBrokennessLevels(Object newValue) {
		if (newValue instanceof List<?>) {
			List<?> shapenessLevels = (List<?>) newValue;
			List<String> newLevels = new ArrayList<String>();
			for (Object object : shapenessLevels) {
				if (object instanceof String) {
					String level = (String) object;
					newLevels.add(level);
				}
			}
			view.setBrokenessLevels(newLevels);
		}
	}

	protected void updateDescription(Object newValue) {
		if (newValue instanceof String) {
			String newDescription = (String) newValue;
			view.setDescription(newDescription);
		}
	}

	protected void updateDirtiness(Object newValue) {
		//current fDirtiness not shown in view
	}

	protected void updateDirtinessLevels(Object newValue) {
		if (newValue instanceof List<?>) {
			List<?> shapenessLevels = (List<?>) newValue;
			List<String> newLevels = new ArrayList<String>();
			for (Object object : shapenessLevels) {
				if (object instanceof String) {
					String level = (String) object;
					newLevels.add(level);
				}
			}
			view.setBrokenessLevels(newLevels);
		}
	}

	protected void updateQualityCurrent(Object newValue) {
		if (newValue instanceof Double) {
			Double quality = (Double) newValue;
			view.setQuality(quality);
		}
	}

	protected void updateQualityMax(Object newValue) {
		if (newValue instanceof Double) {
			Double quality = (Double) newValue;
			view.setQualityMax(quality);
		}
	}

	protected void updateQualityMin(Object newValue) {
		if (newValue instanceof Double) {
			Double quality = (Double) newValue;
			view.setQualityMin(quality);
		}
	}

	protected void updateType(Object newValue) {
		if (newValue instanceof String) {
			String type = (String) newValue;
			view.setType(type);
		}
	}

	protected void updateWeight(Object newValue) {
		if (newValue instanceof Float) {
			Float weight = (Float) newValue;
			view.setWeight(weight);
		}
	}

	protected void updateName(Object newValue) {
		if(newValue instanceof String){
			String value = (String)newValue;
			view.setItemName(value);
		}
	}

	protected void changePropertyInModel(int index){
		switch (index) {
			case ICompositeEditItem.INDEX_VALUE_DESCRIPTION:
				changeDescription(view.getDescription());
				break;
			case ICompositeEditItem.INDEX_VALUE_NAME:
				changeName(view.getItemName());
				break;
			case ICompositeEditItem.INDEX_VALUE_QUALITY_CURRENT:
				changeQualityCurrent(view.getQuality());
				break;
			case ICompositeEditItem.INDEX_VALUE_QUALITY_MAX:
				changeQualityMax(view.getQualityMax());
				break;
			case ICompositeEditItem.INDEX_VALUE_QUALITY_MIN:
				changeQualityMin(view.getQualityMin());
				break;
			case ICompositeEditItem.INDEX_VALUE_TYPE:
				changeType(view.getType());
				break;
			case ICompositeEditItem.INDEX_VALUE_WEIGHT:
				changeWeight(view.getWeight());
				break;
		}
	}

	protected void changeDescription(String description) {
		if( ! changed.getDescription().equals(description)){
			changed.setDescription(description);
		}
	}

	protected void changeName(String name) {
		if( ! changed.getName().equals(name)){
			changed.setName(name);
		}
	}

	protected void changeQualityCurrent(Double quality) {
		if( ! changed.getQuality().equals(quality)){
			changed.setQuality(quality);
		}
	}

	protected void changeQualityMax(Double qualityMax) {
		if( ! changed.getQualityMax().equals(qualityMax)){
			changed.setQualityMax(qualityMax);
		}
	}

	protected void changeQualityMin(Double qualityMin) {
		if( ! changed.getQualityMin().equals(qualityMin)){
			changed.setQualityMin(qualityMin);
		}
	}

	protected void changeType(String type) {
		if( ! changed.getType().equals(type)){
			changed.setType(type);
		}
	}

	protected void changeWeight(Float weight) {
		if( ! changed.getWeight().equals(weight)){
			changed.setWeight(weight);
		}

	}






	 public void setCompositeEditItem(ICompositeEditItem compositeEditItem) {
    	unRegisterListenersAtView(view);
    	view = compositeEditItem;
        updateViewData();
        registerListenersAtView(view);
    }

    public void removeCompositeEditItem() {
        unRegisterListenersAtView(view);
        view = null;
    }

    public Item getItem() {
        return changed;
    }

    public void setItem(Item item) {
    	try {
			unRegisterModelListeners(this.changed);
			this.original = (Item) item.clone();
			this.changed = item;
			registerModelListeners(this.changed);
		} catch (CloneNotSupportedException e) {
			logger.error("item cloning not possible",e);
		}
		updateViewData();
    }



}
